package com.aabte.lock.jedis.v2;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

public abstract class AbstractLock implements Lock {

    protected volatile boolean locked;

    private Thread exclusiveOwnerThread;

    public void lock(){
        try {
            lock(false, 0, null, false);
        } catch (InterruptedException e) {
            // nothing
        }
    }

    public void lockInterruptibly() throws InterruptedException{
        lock(false, 0, null, true);
    }

    public boolean tryLock(long time, TimeUnit unit){
        try {
            return lock(true, time, unit, false);
        } catch (InterruptedException e) {
            // nothing
        }
        return false;
    }

    public boolean tryLockInterruptibly(long time, TimeUnit unit) throws InterruptedException{
        return lock(true, time, unit, true);
    }

    public void unlock(){
        if (Thread.currentThread() != getExclusiveOwnerThread()) {
            throw new IllegalMonitorStateException("current thread does not hold the lock");
        }
        unlock0();
        setExclusiveOwnerThread(null);
    }

    protected void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }

    protected final Thread getExclusiveOwnerThread() {
        return exclusiveOwnerThread;
    }

    protected abstract void unlock0();

    /**
     * 阻塞式获取锁的实现
     *
     * @param useTimeout 是否超时
     * @param time 获取锁的等待时间
     * @param unit 时间单位
     * @param interrupt
     *            是否响应中断
     * @return
     * @throws InterruptedException
     */
    protected abstract boolean lock(boolean useTimeout, long time, TimeUnit unit, boolean interrupt)
            throws InterruptedException;

}
